package com.wryyyyy.real.impl;

import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.QueryApi;
import com.influxdb.query.FluxTable;
import com.wryyyyy.entity.CirculatingWaterQuality;
import com.wryyyyy.real.ICirculatingWaterDao;
import com.wryyyyy.utils.FluxFilter;
import com.wryyyyy.utils.FluxResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static com.wryyyyy.utils.SystemConstants.CIRCULATING_WATER_BUCKET;

@Slf4j
@Component
public class CirculatingWaterDao implements ICirculatingWaterDao {
    @Resource
    private InfluxDBClient influxDBClient;

    @Override
    public Double getPassingRate(List<String> countryIds) {
        QueryApi queryApi = influxDBClient.getQueryApi();

        StringBuilder countryIdFilter = FluxFilter.getCountryIdFilter(countryIds);

        String flux = "t1=from(bucket: \""+CIRCULATING_WATER_BUCKET+"\")\n" +
                "  |> range(start: -24h)\n" +
                "  |> filter(fn: (r) => r[\"_measurement\"] == \"circulating_water_quality\")\n" +
                countryIdFilter + "\n" +
                "  |> map(fn: (r)=> {\n" +
                "      return if ((r[\"_field\"] == \"pH\" and (r[\"_value\"] < 8.5 or r[\"_value\"] > 9.5)) or (r[\"_field\"] == \"alkalinity\" and (r[\"_value\"] < 400 or r[\"_value\"] > 900)) or (r[\"_field\"] == \"ss\" and r[\"_value\"] > 50) or (r[\"_field\"] == \"Ca2\" and (r[\"_value\"] < 30 or r[\"_value\"] > 200)) or (r[\"_field\"] == \"Mg2\" and r[\"_value\"] > 60) or (r[\"_field\"] == \"Fe23\" and r[\"_value\"] > 0.5))\n" +
                "      then {\"passing\": 0} else {\"passing\":1}\n" +
                "    })\n" +
                "|> sum(column: \"passing\")\n" +
                "t2=from(bucket: \"circulating_water\")\n" +
                "  |> range(start: -24h)\n" +
                "  |> filter(fn: (r) => r[\"_measurement\"] == \"circulating_water_quality\")\n" +
                "  |> map(fn: (r)=> {\n" +
                "      return {\"total\": 1}\n" +
                "    })\n" +
                "  |> sum(column: \"total\")\n" +
                "  union(tables: [t1,t2])";

        List<FluxTable> tables = queryApi.query(flux);

        return FluxResult.toPercentage(tables);
    }

    @Override
    public CirculatingWaterQuality getContent(List<String> countryIds) {
        QueryApi queryApi = influxDBClient.getQueryApi();

        StringBuilder countryIdFilter = FluxFilter.getCountryIdFilter(countryIds);

        String flux = "from(bucket: \""+CIRCULATING_WATER_BUCKET+"\")\n" +
                "  |> range(start: -24h)\n" +
                "  |> filter(fn: (r) => r[\"_measurement\"] == \"circulating_water_quality\")\n" +
                countryIdFilter + "\n" +
                "  |> drop(columns: [\"country_id\"])\n" +
                "  |> mean()\n" +
                "  |> yield(name: \"result\")";

        List<FluxTable> tables = queryApi.query(flux);

        return FluxResult.toBean(tables, CirculatingWaterQuality.class);
    }

    @Override
    public Map<LocalDateTime, Double> getAmount(List<String> countryIds) {
        QueryApi queryApi = influxDBClient.getQueryApi();

        StringBuilder countryIdFilter = FluxFilter.getCountryIdFilter(countryIds);

        String flux = "from(bucket: \""+CIRCULATING_WATER_BUCKET+"\")\n" +
                "  |> range(start: -24h)\n" +
                "  |> filter(fn: (r) => r[\"_measurement\"] == \"circulating_water_amount\")\n" +
                countryIdFilter + "\n" +
                "  |> drop(columns: [\"country_id\"])\n" +
                "  |> window(every: 2h)\n" +
                "  |> sum()\n" +
                "  |> yield(name: \"result\")";

        List<FluxTable> tables = queryApi.query(flux);

        return FluxResult.toEach(tables);
    }
}